package com.example.englishwars2d;

import java.io.IOException;
import java.util.List;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.MediaPlayer;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;

import com.badlogic.androidgames.framework.Audio;
import com.badlogic.androidgames.framework.FileIO;
import com.badlogic.androidgames.framework.Game;
import com.badlogic.androidgames.framework.Graphics;
import com.badlogic.androidgames.framework.Input;
import com.badlogic.androidgames.framework.Screen;
import com.badlogic.androidgames.framework.impl.AndroidAudio;
import com.badlogic.androidgames.framework.impl.AndroidFileIO;
import com.badlogic.androidgames.framework.impl.AndroidInput;
import com.badlogic.androidgames.framework.impl.GLGraphics;
import com.example.englishwars2d.CollisionTest.Enemy;
import com.example.englishwars2d.CollisionTest.EnemyType;

public abstract class GLGame extends Activity implements Game, Renderer {
	boolean firstTimeCreate = true;
    static final float WORLD_WIDTH = 9.6f;
    static final float WORLD_HEIGHT = 4.8f;
	MediaPlayer mPlayer;
	String mQuestion, mMeaning, mPictureFile;
    EnemyType eType;
    enum GLGameState {
        Initialized,
        Running,
        Paused,
        Finished,
        Idle
    }

	boolean isCorrectAnswer;
    GLSurfaceView glView;    
    GLGraphics glGraphics;
    Audio audio;
    Input input;
    FileIO fileIO;
    Screen screen;
    GLGameState state = GLGameState.Initialized;
    Object stateChanged = new Object();
    long startTime = System.nanoTime();
    float addedTime;
    boolean isUpdated;
    WakeLock wakeLock;
//	boolean isAnswerInputed = false;
	EditText et;
	boolean isUpdating = false;
	MyDatabaseOpenHelper mDBHelper;
	Cursor mCursor = null;
//	ImageView iv;
//	ImageView ivCount;
//	AnimationDrawable mAni;
	ProgressBar mProgCircle;
	public List<Enemy> targets;
	boolean isConfirmClicked;
	TextView mScore;
	TextView mAnswerView;
//	Handler mHandler;
	
    @Override 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		Intent intent = getIntent();
		int song_num = intent.getIntExtra("song_num", 0);
		Log.i("Test", "select: "+song_num);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);
        DisplayMetrics metrics = new DisplayMetrics();

        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int screenWidth = metrics.widthPixels;
        int screenHeight = metrics.heightPixels;

        setContentView(R.layout.activity_main_org);
        glView = (OpenGLES10SurfaceView)findViewById(R.id.surfaceView1);
        glView.setRenderer(this);
        mProgCircle = (ProgressBar)findViewById(R.id.progcircle);
//		iv = (ImageView)findViewById(R.id.pause);
//		ivCount = (ImageView)findViewById(R.id.count);
//		mAni = (AnimationDrawable)ivCount.getBackground();
		Button btn = (Button) findViewById(R.id.submit);
		btn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {

				state = GLGameState.Paused;
//				isAnswerInputed = false;

				InputMethodManager manager = (InputMethodManager)
				getSystemService(GLGame.this.INPUT_METHOD_SERVICE);
				manager.hideSoftInputFromWindow(et.getWindowToken(), 0);
				if (isConfirmClicked)
					return;
				String answer = et.getText().toString();
				answer = ConvertUtil.removeUnusedChar(answer);
				mQuestion = ConvertUtil.removeUnusedChar(mQuestion);
//				if (mQuestion.equalsIgnoreCase(answer)) {
					
					mProgCircle.setVisibility(View.VISIBLE);
					startTime = System.nanoTime();
					state = GLGameState.Running;
					for (int i=0 ;i<targets.size(); i++){
						Enemy enemy = targets.get(i);
						new MyAsyncTask().execute(enemy);
					}
//				}
				Log.i("Test", answer);
			}

		});
		btn = (Button) findViewById(R.id.hear);
		btn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
//				if (state == GLGameState.Running)
//					state = GLGameState.Paused;
//				else 
//					state = GLGameState.Running;
				playSound();
			}
		});
		mScore = (TextView)findViewById(R.id.Score);
		mAnswerView = (TextView)findViewById(R.id.answerView);
		mAnswerView.setWidth((int)(screenWidth*0.6));
		et = (EditText) findViewById(R.id.answer);
		et.setOnEditorActionListener(new OnEditorActionListener() {

			public boolean onEditorAction(TextView v, int actionId,
					KeyEvent event) {
				Log.i("Test", "return key!!");
				mProgCircle.setVisibility(View.INVISIBLE);
//				iv.setVisibility(ImageView.INVISIBLE);
//				ivCount.setVisibility(ImageView.VISIBLE);
//				mAni.start();
				startTime = System.nanoTime();
				state = GLGameState.Running;
//				isAnswerInputed = false;
				return false;
			}
		});

		et.setOnTouchListener(new OnTouchListener() {

			public boolean onTouch(View v, MotionEvent event) {
				Log.i("Test", "Touched!!");
				mProgCircle.setVisibility(View.VISIBLE);
//				isAnswerInputed = true;
				state = GLGameState.Paused;
//				iv.setVisibility(ImageView.VISIBLE);
//				showSoftkeyboard();
				return false;
			}
		});
        
        glGraphics = new GLGraphics(glView);
        fileIO = new AndroidFileIO(getAssets());
        audio = new AndroidAudio(this);
        input = new AndroidInput(this, glView, 1, 1);
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame");        
		mDBHelper = new MyDatabaseOpenHelper(this);
		try {
			if (mCursor != null) {
				mCursor.close();
				mCursor = null;
			}
			SQLiteDatabase db = mDBHelper.getReadableDatabase();
			String sql = "SELECT "
					+DBConstant.QuizTable.QUIZ_NUM+", "
					+DBConstant.QuizTable.SENTENCE+", "
					+DBConstant.QuizTable.HINT_WORD+", "
					+ DBConstant.QuizTable.PICTURE_FILE
					+" FROM " + DBConstant.QuizTable.TABLE_NAME
					+" WHERE " +
					DBConstant.QuizTable.SONG_NUM + " = ? ";
			String[] argument = { String.valueOf(song_num) };
			mCursor = db.rawQuery(sql, argument);
//			if (mCursor.moveToNext()){
//				mQuestion = mCursor.getString(1);
//				mMeaning = mCursor.getString(2);
//				mPictureFile = mCursor.getString(3);
//				Log.i("Test", "question:"+mQuestion);
//			}
		} catch (Exception e) {
			Log.e("Test", e.getMessage());
		}

    }
    
    public class MyAsyncTask extends AsyncTask<Enemy, Void, Enemy> {
    	
    	@Override
		protected void onPreExecute() {
    		isConfirmClicked = true;
			super.onPreExecute();
		}


		@Override
    	protected Enemy doInBackground(Enemy... enemies) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
    		return enemies[0];
    	}

    	
		@Override
		protected void onPostExecute(Enemy target) {
			super.onPostExecute(target);
			final Enemy temp= target; 
			mProgCircle.setVisibility(View.INVISIBLE);
//			((AndroidInput)input).deletePool();
//			Toast.makeText(GLGame.this, "맞았습니다!!", Toast.LENGTH_SHORT).show();
			new AlertDialog.Builder(GLGame.this).setTitle("맞았습니다!!")
			.setMessage("뜻: "+mMeaning)
			.setIcon(R.drawable.icon)
			.setPositiveButton("닫기", new DialogInterface.OnClickListener(){

				public void onClick(DialogInterface arg0, int arg1) {
					isCorrectAnswer  =true;
					mAnswerView.setText("");
//					et.setText("");
//					isUpdating = true;
//					if (mCursor.moveToNext()){
//						mQuestion = mCursor.getString(1);
//						Log.i("Test", "다시 읽은 question:"+mQuestion);
//					}
//					isUpdating = false;
					isConfirmClicked = false;
				}
				
			})
			.show();
			
//			et.setText("");
		}

    }


	private void playSound() {
        mPlayer.reset();

		String loc = "http://translate.google.com/translate_tts?tl=en&q="+ mQuestion;
		Log.i("Test", loc);
		Uri uri = Uri.parse(loc);
		if (LoadMedia(uri)){
			try {
				mPlayer.start();
			} catch (Exception e) {
				// Toast.makeText(MyApplication.getContext(), "error : " +
				// e.getMessage(), 0).show();
			}		
		}
	}

    // 항상 준비 상태여야 한다.
    boolean LoadMedia(Uri uri) {
		try {
			mPlayer.setDataSource(this, uri);
			mPlayer.prepare();
		} catch (IllegalArgumentException e) {
			return false;
		} catch (IllegalStateException e) {
			return false;
		} catch (IOException e) {
			return false;
		}

		return true;
    }
    
    public void onResume() {
        super.onResume();
        glView.onResume();
        wakeLock.acquire();
    }
    
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {        
        glGraphics.setGL(gl);
//        if (firstTimeCreate) {
//			Assets.load(this);
//			firstTimeCreate = false;
//		} else {
//			Assets.reload();
//		}       
        synchronized(stateChanged) {
            if(state == GLGameState.Initialized)
                screen = getStartScreen();
            state = GLGameState.Running;
            screen.resume();
            startTime = System.nanoTime();
        }        
    }
    
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {        
    }

    @Override
    public void onDrawFrame(GL10 gl) {                
        GLGameState state = null;
        
        synchronized(stateChanged) {
            state = this.state;
        }
        
        if(state == GLGameState.Running) {
            float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;
            startTime = System.nanoTime();
            if (isUpdated){
            	addedTime +=deltaTime;
            }  
//            Log.i("Test", "addedTime: "+addedTime);
//    		if (deltaTime > (isAnswerInputed ? 5 : 3)) {
////    			startTime = System.nanoTime();
//
////    			root.update(1);
//    		}
            screen.update(deltaTime);
            screen.present(deltaTime);
        }
        
        if(state == GLGameState.Paused) {
            screen.pause();            
            synchronized(stateChanged) {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }
        }
        
        if(state == GLGameState.Finished) {
            screen.pause();
            screen.dispose();
            synchronized(stateChanged) {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }            
        }
    }   
    
    @Override 
    public void onPause() {        
        synchronized(stateChanged) {
            if(isFinishing())            
                state = GLGameState.Finished;
            else
                state = GLGameState.Paused;
            while(true) {
                try {
                    stateChanged.wait();
                    break;
                } catch(InterruptedException e) {         
                }
            }
        }
        wakeLock.release();
        glView.onPause();  
        super.onPause();
    }    
    
    public GLGraphics getGLGraphics() {
        return glGraphics;
    }  
    
    @Override
    public Input getInput() {
        return input;
    }

    @Override
    public FileIO getFileIO() {
        return fileIO;
    }

    @Override
    public Graphics getGraphics() {
        throw new IllegalStateException("We are using OpenGL!");
    }

    @Override
    public Audio getAudio() {
        return audio;
    }

    @Override
    public void setScreen(Screen screen) {
        if (screen == null)
            throw new IllegalArgumentException("Screen must not be null");

        this.screen.pause();
        this.screen.dispose();
        screen.resume();
        screen.update(0);
        this.screen = screen;
    }

    @Override
    public Screen getCurrentScreen() {
        return screen;
    }
}
